Escola de Métodos em Ciência Política
Até agora, estudamos os principais ferramentas de transformação de dados do dplyr. Agora vamos aumentar nossa caixa-de-ferramentas com tidyr
Hadley Wickham https://r4ds.hadley.nz/data-tidy#sec-tidy-data
Enquanto o dplyr faz recortes na base (com filter()e select()) e adições simples (mutate(), summarise()), o tidyr mexe no formato da tabela (pivot_longer e pivot_wider) e faz modificações menos triviais.
tidyr geralmente vêm em pares com seus inversos:
pivot_longer e pivot_wider (substituindo gather() e spread())nest() e unnest(),separate() e unite()https://r4ds.hadley.nz/data-transform
pivot_wider() e pivot_longer()pivot_wider()empilha o banco de dados
decisoes %>%
filter(!is.na(id_decisao)) %>%
select(id_decisao:data_registro) %>%
pivot_longer(!id_decisao,
names_to = "tipo", # diz a varável onde entrarão os nomes
values_to = "info" # diz a variável onde entrarão os valores
)# A tibble: 69,996 × 3
id_decisao tipo info
<chr> <chr> <chr>
1 11094999 n_processo 0057003-20.2017.8.26.0000
2 11094999 classe_assunto Habeas Corpus / Homicídio Simples
3 11094999 municipio Cosmópolis
4 11094999 camara 3ª Câmara de Direito Criminal
5 11094999 data_decisao 19/12/2017
6 11094999 data_registro 19/12/2017
7 11093733 n_processo 0052762-03.2017.8.26.0000
8 11093733 classe_assunto Habeas Corpus / Roubo
9 11093733 municipio São Paulo
10 11093733 camara 3ª Câmara de Direito Criminal
# ℹ 69,986 more rows
gather()pivot_longerdecisoes %>%
filter(!is.na(id_decisao)) %>%
select(id_decisao:data_registro) %>%
# 1. nome da coluna que vai guardar os nomes de colunas empilhadas
# 2. nome da coluna que vai guardar os valores das colunas
# 3. seleção das colunas a serem empilhadas
gather(key="variavel", value="valor", -id_decisao) %>%
arrange(id_decisao)# A tibble: 69,996 × 3
id_decisao variavel valor
<chr> <chr> <chr>
1 11026431 n_processo 0000009-51.2015.8.26.0546
2 11026431 classe_assunto Apelação / Tráfico de Drogas e Condutas Afins
3 11026431 municipio Itapira
4 11026431 camara 5ª Câmara de Direito Criminal
5 11026431 data_decisao 30/11/2017
6 11026431 data_registro 01/12/2017
7 11026432 n_processo 0002267-69.2013.8.26.0654
8 11026432 classe_assunto Apelação / Furto Qualificado
9 11026432 municipio Vargem Grande Paulista
10 11026432 camara 5ª Câmara de Direito Criminal
# ℹ 69,986 more rows
pivot_longer() em uma base que faça mais sentidoVamos usar a base relig_income do tidyr como exemplo, olhando 3 variáveis:
# A tibble: 18 × 11
religion `<$10k` `$10-20k` `$20-30k` `$30-40k` `$40-50k` `$50-75k` `$75-100k`
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Agnostic 27 34 60 81 76 137 122
2 Atheist 12 27 37 52 35 70 73
3 Buddhist 27 21 30 34 33 58 62
4 Catholic 418 617 732 670 638 1116 949
5 Don’t k… 15 14 15 11 10 35 21
6 Evangel… 575 869 1064 982 881 1486 949
7 Hindu 1 9 7 9 11 34 47
8 Histori… 228 244 236 238 197 223 131
9 Jehovah… 20 27 24 24 21 30 15
10 Jewish 19 19 25 25 30 95 69
11 Mainlin… 289 495 619 655 651 1107 939
12 Mormon 29 40 48 51 56 112 85
13 Muslim 6 7 9 10 9 23 16
14 Orthodox 13 17 23 32 32 47 38
15 Other C… 9 7 11 13 13 14 18
16 Other F… 20 33 40 46 49 63 46
17 Other W… 5 2 3 4 2 7 3
18 Unaffil… 217 299 374 365 341 528 407
# ℹ 3 more variables: `$100-150k` <dbl>, `>150k` <dbl>,
# `Don't know/refused` <dbl>
pivot_longer() em açãotidyr::relig_income %>%
pivot_longer(!religion,
names_to = "income", # diz a varável onde entrarão os nomes
values_to = "count" # diz a variável onde entrarão os valores
)# A tibble: 180 × 3
religion income count
<chr> <chr> <dbl>
1 Agnostic <$10k 27
2 Agnostic $10-20k 34
3 Agnostic $20-30k 60
4 Agnostic $30-40k 81
5 Agnostic $40-50k 76
6 Agnostic $50-75k 137
7 Agnostic $75-100k 122
8 Agnostic $100-150k 109
9 Agnostic >150k 84
10 Agnostic Don't know/refused 96
# ℹ 170 more rows
pivot_widerespalha uma variável nas colunas e preenche com outra variável
decisoes %>%
filter(!is.na(id_decisao)) %>%
select(id_decisao:data_registro) %>%
pivot_longer(!id_decisao,
names_to = "tipo", # diz a varável onde entrarão os nomes
values_to = "info" # diz a variável onde entrarão os valores
) %>%
pivot_wider(names_from = "tipo", # 1. coluna a ser espalhada
values_from = "info") # 2. valores da coluna# A tibble: 11,666 × 7
id_decisao n_processo classe_assunto municipio camara data_decisao
<chr> <chr> <chr> <chr> <chr> <chr>
1 11094999 0057003-20.2017.8.26… Habeas Corpus… Cosmópol… 3ª Câ… 19/12/2017
2 11093733 0052762-03.2017.8.26… Habeas Corpus… São Paulo 3ª Câ… 19/12/2017
3 11093677 0055169-79.2017.8.26… Habeas Corpus… Ribeirão… 3ª Câ… 19/12/2017
4 11093270 9000580-82.2017.8.26… Agravo de Exe… Araçatuba 8ª Câ… 14/12/2017
5 11093374 0052938-79.2017.8.26… Mandado de Se… São Paulo 8ª Câ… 14/12/2017
6 11093320 9000723-79.2017.8.26… Agravo de Exe… Presiden… 8ª Câ… 14/12/2017
7 11091506 0003276-86.2015.8.26… Apelação / Tr… Bertioga 8ª Câ… 14/12/2017
8 11093326 9000298-11.2017.8.26… Agravo de Exe… Taubaté 8ª Câ… 14/12/2017
9 11092475 0004653-39.2015.8.26… Apelação / Tr… Aparecida 8ª Câ… 14/12/2017
10 11093773 2221930-66.2017.8.26… Habeas Corpus… Jandira 3ª Câ… 19/12/2017
# ℹ 11,656 more rows
# ℹ 1 more variable: data_registro <chr>
spread()spread() é a função inversa de gather
substituída por pivot_wider
decisoes %>%
filter(!is.na(id_decisao)) %>%
select(id_decisao:data_registro) %>%
gather(key, value, -id_decisao) %>%
# 1. coluna a ser espalhada
# 2. valores da coluna
spread(key, value)# A tibble: 11,666 × 7
id_decisao camara classe_assunto data_decisao data_registro municipio
<chr> <chr> <chr> <chr> <chr> <chr>
1 11026431 5ª Câmara de … Apelação / Tr… 30/11/2017 01/12/2017 Itapira
2 11026432 5ª Câmara de … Apelação / Fu… 30/11/2017 01/12/2017 Vargem G…
3 11026433 5ª Câmara de … Apelação / Ro… 30/11/2017 01/12/2017 Sertãozi…
4 11026434 12ª Câmara de… Agravo de Exe… 18/10/2017 01/12/2017 Ribeirão…
5 11026435 15ª Câmara de… Apelação / Tr… 30/11/2017 01/12/2017 São Paulo
6 11026442 5ª Câmara de … Apelação / Es… 30/11/2017 01/12/2017 Jales
7 11026445 13ª Câmara de… Apelação / Us… 30/11/2017 01/12/2017 Santa Fé…
8 11026453 5ª Câmara de … Apelação / Cr… 30/11/2017 01/12/2017 Franca
9 11026455 12ª Câmara de… Apelação / Ro… 05/07/2017 01/12/2017 Franca
10 11026456 12ª Câmara de… Apelação / Ro… 03/05/2017 01/12/2017 São José…
# ℹ 11,656 more rows
# ℹ 1 more variable: n_processo <chr>
Qual juiz julga a maior proporção de processos que tratam de drogas?
Dicas:
– construa um data.frame contendo as colunas juiz, n_processos_drogas, n_processos_n_drogas e total_processos,
– remodele os dados para haver um juiz por linha utilizando pivot_wider()
decisoes %>%
filter(!is.na(txt_decisao)) %>%
mutate(txt_decisao = tolower(txt_decisao),
droga = str_detect(txt_decisao,
"droga|entorpecente|psicotr[óo]pico|maconha|haxixe|coca[íi]na"),
droga=case_when(
droga==TRUE ~ "droga",
droga==FALSE ~ "n_droga"
)) %>%
group_by(juiz,droga) %>%
summarise(n=n()) %>%
pivot_wider(names_from = droga,
values_from = n,
values_fill = 0) %>%
mutate(total=droga+n_droga,
proporcao=droga/total)# A tibble: 65 × 5
# Groups: juiz [65]
juiz droga n_droga total proporcao
<chr> <int> <int> <int> <dbl>
1 Airton Vieira 23 131 154 0.149
2 Alcides Malossi Junior 23 72 95 0.242
3 Alexandre Almeida 41 122 163 0.252
4 Amaro Thomé 36 96 132 0.273
5 Andrade Sampaio 35 79 114 0.307
6 Angélica de Almeida 2 6 8 0.25
7 Antonio Tadeu Ottoni 0 1 1 0
8 Bandeira Lins 0 2 2 0
9 Camargo Aranha Filho 32 109 141 0.227
10 Camilo Léllis 32 133 165 0.194
# ℹ 55 more rows
Elabore uma tabela com a quantidade mensal de decisões por juiz, sendo cada mês uma coluna.
Dica: use data_decisao dmy() e month()
# A tibble: 99 × 13
juiz Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
<chr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 Alex… 37 0 0 0 0 0 0 0 0 0 58 44
2 Fran… 37 0 0 0 0 0 0 0 0 0 74 115
3 Ivo … 8 0 0 0 0 0 0 0 0 0 59 69
4 José… 25 0 0 0 0 0 0 0 0 0 34 34
5 Luiz… 35 0 0 0 0 0 0 1 0 1 0 70
6 Mach… 17 0 0 0 0 0 0 0 1 0 70 94
7 Márc… 34 0 0 0 0 0 0 0 0 0 14 27
8 Rica… 11 0 0 0 0 0 0 0 0 0 35 118
9 Silm… 34 0 0 0 0 0 0 0 0 1 22 93
10 Sérg… 58 0 0 0 0 0 0 0 0 1 48 66
# ℹ 89 more rows
unite junta duas ou mais colunas usando algum separador (_, por exemplo).separate faz o inverso de unite, e uma coluna em várias usando um separador.[1] "Habeas Corpus / Homicídio Simples"
[2] "Habeas Corpus / Roubo"
[3] "Habeas Corpus / DIREITO PENAL"
[4] "Agravo de Execução Penal / Pena Privativa de Liberdade"
[5] "Mandado de Segurança / Crimes do Sistema Nacional de Armas"
[6] "Agravo de Execução Penal / Pena Privativa de Liberdade"
[7] "Apelação / Tráfico de Drogas e Condutas Afins"
[8] "Agravo de Execução Penal / Livramento Condicional"
Vamos separar a coluna classe_assunto em duas colunas
coluna classe e coluna assunto
Existe separador? -> sim, /
Usei count apenas em assunto
# A tibble: 152 × 2
assunto n
<chr> <int>
1 Tráfico de Drogas e Condutas Afins 2441
2 Pena Privativa de Liberdade 1106
3 Roubo Majorado 1093
4 Furto Qualificado 838
5 Roubo 780
6 Progressão de Regime 607
7 Furto 450
8 Receptação 353
9 Homicídio Qualificado 329
10 Crimes de Trânsito 322
# ℹ 142 more rows
nest() e unnest()nest() e unnest() são operações inversas e servem para tratar dados complexos, como o que temos em processos
unnest()As list columns são uma forma condensada de guardar dados que estariam em múltiplas tabelas. Por exemplo, uma alternativa à colocar as partes numa list column seria guardar a tabela d_partes separadamente.
Rows: 37,579
Columns: 5
$ n_processo <chr> "0000003-71.2016.8.26.0073", "0000003-71.2016.8.26.0073", "…
$ id <int> 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1,…
$ name <chr> "JOSE MARIA JUSTINO NETO", "Defensoria Pública do Estado de…
$ part <chr> "Apelante", "Apelante", "Apelado", "Apelante", "Apelante", …
$ role <chr> "Apelante", "Apelante", "Apelado", "Apelante", "Advogado", …
Para retirar duplicatas, utilizar distinct. Ele considera apenas a primeira linha em que encontra um padrão para as combinações de variáveis escolhidas e descarta as demais.
# A tibble: 315 × 1
municipio
<chr>
1 Cosmópolis
2 São Paulo
3 Ribeirão Preto
4 Araçatuba
5 Presidente Prudente
6 Bertioga
7 Taubaté
8 Aparecida
9 Jandira
10 Flórida Paulista
# ℹ 305 more rows
Para manter as demais colunas, use .keep_all=:
# A tibble: 2,760 × 9
id_decisao n_processo classe_assunto municipio camara data_decisao
<chr> <chr> <chr> <chr> <chr> <chr>
1 11094999 0057003-20.2017.8.26… Habeas Corpus… Cosmópol… 3ª Câ… 19/12/2017
2 11093733 0052762-03.2017.8.26… Habeas Corpus… São Paulo 3ª Câ… 19/12/2017
3 11093677 0055169-79.2017.8.26… Habeas Corpus… Ribeirão… 3ª Câ… 19/12/2017
4 11093270 9000580-82.2017.8.26… Agravo de Exe… Araçatuba 8ª Câ… 14/12/2017
5 11093374 0052938-79.2017.8.26… Mandado de Se… São Paulo 8ª Câ… 14/12/2017
6 11093320 9000723-79.2017.8.26… Agravo de Exe… Presiden… 8ª Câ… 14/12/2017
7 11091506 0003276-86.2015.8.26… Apelação / Tr… Bertioga 8ª Câ… 14/12/2017
8 11093326 9000298-11.2017.8.26… Agravo de Exe… Taubaté 8ª Câ… 14/12/2017
9 11092475 0004653-39.2015.8.26… Apelação / Tr… Aparecida 8ª Câ… 14/12/2017
10 11093773 2221930-66.2017.8.26… Habeas Corpus… Jandira 3ª Câ… 19/12/2017
# ℹ 2,750 more rows
# ℹ 3 more variables: data_registro <chr>, juiz <chr>, txt_decisao <chr>
janitor::get_dupes()Use janitor::get_dupes() para averiguar os casos em que há repetição de combinações de colunas.
janitor::get_dupes() em ação# A tibble: 114 × 10
n_processo dupe_count id_decisao classe_assunto municipio camara data_decisao
<chr> <int> <chr> <chr> <chr> <chr> <chr>
1 <NA> 65 <NA> <NA> <NA> <NA> <NA>
2 <NA> 65 <NA> <NA> <NA> <NA> <NA>
3 <NA> 65 <NA> <NA> <NA> <NA> <NA>
4 <NA> 65 <NA> <NA> <NA> <NA> <NA>
5 <NA> 65 <NA> <NA> <NA> <NA> <NA>
6 <NA> 65 <NA> <NA> <NA> <NA> <NA>
7 <NA> 65 <NA> <NA> <NA> <NA> <NA>
8 <NA> 65 <NA> <NA> <NA> <NA> <NA>
9 <NA> 65 <NA> <NA> <NA> <NA> <NA>
10 <NA> 65 <NA> <NA> <NA> <NA> <NA>
# ℹ 104 more rows
# ℹ 3 more variables: data_registro <chr>, juiz <chr>, txt_decisao <chr>
janitorJanitor exemplos http://sfirke.github.io/janitor/articles/janitor.html
Missing e imputação https://www.analyticsvidhya.com/blog/2016/03/tutorial-powerful-packages-imputing-missing-values/
Outliers (critérios, limpeza e gráficos)
stringi e stringr
Para juntar tabelas, usar inner_join, left_join, anti_join, etc.
PREFIRA LEFT JOIN
Vamos criar dois objetos com uma chave primária comum: party
party size
1 PT 61
2 PP 50
3 MDB 51
4 PSDB 49
5 DEM 43
6 PR 40
7 PSD 37
8 PSB 26
9 PRB 21
10 PDT 19
11 PODEMOS 17
12 PTB 16
13 PROS 11
14 SD 10
15 PCdoB 10
16 PSC 9
17 PSL 8
18 PPS 8
19 PSOL 6
20 PATRI 5
21 AVANTE 5
22 PV 3
23 PHS 4
24 REDE 2
25 PPL 1
# A tibble: 30 × 3
party president partypresid
<chr> <chr> <chr>
1 AVANTE Ciro PDT
2 DC Eymael DC
3 DEM Alckmin PSDB
4 MDB Meirelles MDB
5 NOVO Amoedo NOVO
6 PATRI Daciolo PATRI
7 PCB Boulos PSOL
8 PCdoB Haddad PT
9 PDT Ciro PDT
10 PHS Meirelles MDB
# ℹ 20 more rows
Rows: 25
Columns: 4
$ party <chr> "PT", "PP", "MDB", "PSDB", "DEM", "PR", "PSD", "PSB", "PRB…
$ size <dbl> 61, 50, 51, 49, 43, 40, 37, 26, 21, 19, 17, 16, 11, 10, 10…
$ president <chr> "Haddad", "Alckmin", "Meirelles", "Alckmin", "Alckmin", "A…
$ partypresid <chr> "PT", "PSDB", "MDB", "PSDB", "PSDB", "PSDB", "PSDB", NA, "…
party size president partypresid
1 PT 61 Haddad PT
2 PP 50 Alckmin PSDB
3 MDB 51 Meirelles MDB
4 PSDB 49 Alckmin PSDB
5 DEM 43 Alckmin PSDB
6 PR 40 Alckmin PSDB
7 PSD 37 Alckmin PSDB
8 PSB 26 <NA> <NA>
9 PRB 21 Alckmin PSDB
10 PDT 19 Ciro PDT
11 PODEMOS 17 Alvaro PODEMOS
12 PTB 16 Alckmin PSDB
13 PROS 11 Haddad PT
14 SD 10 Alckmin PSDB
15 PCdoB 10 Haddad PT
16 PSC 9 Alvaro PODEMOS
17 PSL 8 Bolsonaro PSL
18 PPS 8 Alckmin PSDB
19 PSOL 6 Boulos PSOL
20 PATRI 5 Daciolo PATRI
21 AVANTE 5 Ciro PDT
22 PV 3 Marina REDE
23 PHS 4 Meirelles MDB
24 REDE 2 Marina REDE
25 PPL 1 Goulart PPL
Rows: 24
Columns: 4
$ party <chr> "PT", "PP", "MDB", "PSDB", "DEM", "PR", "PSD", "PRB", "PDT…
$ size <dbl> 61, 50, 51, 49, 43, 40, 37, 21, 19, 17, 16, 11, 10, 10, 9,…
$ president <chr> "Haddad", "Alckmin", "Meirelles", "Alckmin", "Alckmin", "A…
$ partypresid <chr> "PT", "PSDB", "MDB", "PSDB", "PSDB", "PSDB", "PSDB", "PSDB…
party size president partypresid
1 PT 61 Haddad PT
2 PP 50 Alckmin PSDB
3 MDB 51 Meirelles MDB
4 PSDB 49 Alckmin PSDB
5 DEM 43 Alckmin PSDB
6 PR 40 Alckmin PSDB
7 PSD 37 Alckmin PSDB
8 PRB 21 Alckmin PSDB
9 PDT 19 Ciro PDT
10 PODEMOS 17 Alvaro PODEMOS
11 PTB 16 Alckmin PSDB
12 PROS 11 Haddad PT
13 SD 10 Alckmin PSDB
14 PCdoB 10 Haddad PT
15 PSC 9 Alvaro PODEMOS
16 PSL 8 Bolsonaro PSL
17 PPS 8 Alckmin PSDB
18 PSOL 6 Boulos PSOL
19 PATRI 5 Daciolo PATRI
20 AVANTE 5 Ciro PDT
21 PV 3 Marina REDE
22 PHS 4 Meirelles MDB
23 REDE 2 Marina REDE
24 PPL 1 Goulart PPL
Rows: 30
Columns: 4
$ party <chr> "PT", "PP", "MDB", "PSDB", "DEM", "PR", "PSD", "PRB", "PDT…
$ size <dbl> 61, 50, 51, 49, 43, 40, 37, 21, 19, 17, 16, 11, 10, 10, 9,…
$ president <chr> "Haddad", "Alckmin", "Meirelles", "Alckmin", "Alckmin", "A…
$ partypresid <chr> "PT", "PSDB", "MDB", "PSDB", "PSDB", "PSDB", "PSDB", "PSDB…
party size president partypresid
1 PT 61 Haddad PT
2 PP 50 Alckmin PSDB
3 MDB 51 Meirelles MDB
4 PSDB 49 Alckmin PSDB
5 DEM 43 Alckmin PSDB
6 PR 40 Alckmin PSDB
7 PSD 37 Alckmin PSDB
8 PRB 21 Alckmin PSDB
9 PDT 19 Ciro PDT
10 PODEMOS 17 Alvaro PODEMOS
11 PTB 16 Alckmin PSDB
12 PROS 11 Haddad PT
13 SD 10 Alckmin PSDB
14 PCdoB 10 Haddad PT
15 PSC 9 Alvaro PODEMOS
16 PSL 8 Bolsonaro PSL
17 PPS 8 Alckmin PSDB
18 PSOL 6 Boulos PSOL
19 PATRI 5 Daciolo PATRI
20 AVANTE 5 Ciro PDT
21 PV 3 Marina REDE
22 PHS 4 Meirelles MDB
23 REDE 2 Marina REDE
24 PPL 1 Goulart PPL
25 DC NA Eymael DC
26 NOVO NA Amoedo NOVO
27 PCB NA Boulos PSOL
28 PRP NA Alvaro PODEMOS
29 PRTB NA Bolsonaro PSL
30 PTC NA Alvaro PODE
Rows: 31
Columns: 4
$ party <chr> "PT", "PP", "MDB", "PSDB", "DEM", "PR", "PSD", "PSB", "PRB…
$ size <dbl> 61, 50, 51, 49, 43, 40, 37, 26, 21, 19, 17, 16, 11, 10, 10…
$ president <chr> "Haddad", "Alckmin", "Meirelles", "Alckmin", "Alckmin", "A…
$ partypresid <chr> "PT", "PSDB", "MDB", "PSDB", "PSDB", "PSDB", "PSDB", NA, "…
party size president partypresid
1 PT 61 Haddad PT
2 PP 50 Alckmin PSDB
3 MDB 51 Meirelles MDB
4 PSDB 49 Alckmin PSDB
5 DEM 43 Alckmin PSDB
6 PR 40 Alckmin PSDB
7 PSD 37 Alckmin PSDB
8 PSB 26 <NA> <NA>
9 PRB 21 Alckmin PSDB
10 PDT 19 Ciro PDT
11 PODEMOS 17 Alvaro PODEMOS
12 PTB 16 Alckmin PSDB
13 PROS 11 Haddad PT
14 SD 10 Alckmin PSDB
15 PCdoB 10 Haddad PT
16 PSC 9 Alvaro PODEMOS
17 PSL 8 Bolsonaro PSL
18 PPS 8 Alckmin PSDB
19 PSOL 6 Boulos PSOL
20 PATRI 5 Daciolo PATRI
21 AVANTE 5 Ciro PDT
22 PV 3 Marina REDE
23 PHS 4 Meirelles MDB
24 REDE 2 Marina REDE
25 PPL 1 Goulart PPL
26 DC NA Eymael DC
27 NOVO NA Amoedo NOVO
28 PCB NA Boulos PSOL
29 PRP NA Alvaro PODEMOS
30 PRTB NA Bolsonaro PSL
31 PTC NA Alvaro PODE
CURSO DE R